package viroyal.com.base.activity.main;

import android.content.Context;
import android.os.Parcel;
import android.text.TextUtils;
import com.suntiago.a.AudioUtil;
import com.suntiago.a.ChinaDateUtil;
import com.suntiago.a.RangeUtil;
import com.suntiago.baseui.activity.base.theMvp.model.IModel;
import com.suntiago.baseui.utils.SPUtils;
import com.suntiago.baseui.utils.log.Slog;
import com.suntiago.network.network.Api;
import com.suntiago.network.network.BaseRspObserver;
import com.suntiago.network.network.ErrorCode;
import com.suntiago.network.network.rsp.BaseResponse;
import org.kymjs.kjframe.KJDB;
import java.util.ArrayList;
import java.util.List;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.schedulers.Schedulers;
import viroyal.com.base.AppConfig;
import viroyal.com.base.BuildConfig;
import viroyal.com.base.activity.splash.SplashAppDelegate;
import viroyal.com.base.common.ConstantsYJ;
import viroyal.com.base.face.rsp.DeviceInfoRsp;
import viroyal.com.base.model.Announced;
import viroyal.com.base.model.FeaturesUploadBean;
import viroyal.com.base.model.HomeInfo;
import viroyal.com.base.model.OwnStyle;
import viroyal.com.base.model.QrCode;
import viroyal.com.base.model.StudentSignRecord;
import viroyal.com.base.model.Volume;
import viroyal.com.base.net.ApiObserver;
import viroyal.com.base.net.PhpApi;
import viroyal.com.base.net.req.FaceRequest;
import viroyal.com.base.net.req.IOTConfigRequest;
import viroyal.com.base.net.req.SwipeRequest;
import viroyal.com.base.net.req.TakePhotoRequest;
import viroyal.com.base.net.req.TokenRequest;
import viroyal.com.base.net.req.UpDateAppInfoRequest;
import viroyal.com.base.net.rsp.AnnouncedResponseS;
import viroyal.com.base.net.rsp.AppInfoRspS;
import viroyal.com.base.net.rsp.FaceUrlResponseS;
import viroyal.com.base.net.rsp.HomeInfoResponseS;
import viroyal.com.base.net.rsp.IOTConfigResponseS;
import viroyal.com.base.net.rsp.MottoResponseS;
import viroyal.com.base.net.rsp.ParentLinkStudentsResponseS;
import viroyal.com.base.net.rsp.QrCodeResponseS;
import viroyal.com.base.net.rsp.SerialNumberS;
import viroyal.com.base.net.rsp.StudentSignRecordResponseS;
import viroyal.com.base.net.rsp.StudentsResponseS;
import viroyal.com.base.net.rsp.StyleResponseS;
import viroyal.com.base.net.rsp.SwipeAllFaceResponseS;
import viroyal.com.base.net.rsp.SwipeResponseS;
import viroyal.com.base.net.rsp.TokenResponseS;
import viroyal.com.base.net.rsp.UpDateAppInfoResponseS;
import viroyal.com.base.net.rsp.WeatherResponseS;
import viroyal.com.dev.broadcast.BroadcastData;
import viroyal.com.dev.splash.ConfigDevice;


/**
 * @author chenjunwei
 * @desc
 * @date 2019/7/4
 */
public class MainModel implements IModel {

  /**
   * 加载首页信息
   */
  Subscription loadHomeInfo(MainDelegate appDelegateBase, Context context) {
    if (appDelegateBase == null
        || ConfigDevice.DEMO_MODE
        || TextUtils.isEmpty(Api.get().getApi())) {
      return null;
    }
    return Api.get().getApi(ApiObserver.class)
        .homeinfo(ConfigDevice.school_id, ConfigDevice.getDeviceId())
        .subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new BaseRspObserver<>(HomeInfoResponseS.class, rsp -> {
          if (ErrorCode.isSuccess(rsp.error_code)) {
            KJDB.getDefaultInstance().deleteByWhere(Volume.class, "1=1");
            SPUtils.getInstance(context).put(ConstantsYJ.SpTag.HOME_INFO, rsp.data);
            HomeInfo homeInfo = rsp.data;
            if (TextUtils.isEmpty(homeInfo.password)) {
              SPUtils.getInstance(context).put(ConstantsYJ.SpTag.PASS_WORD, "84159009");
            } else {
              SPUtils.getInstance(context).put(ConstantsYJ.SpTag.PASS_WORD, homeInfo.password);
            }
            appDelegateBase.updatePassword();
            KJDB.getDefaultInstance().save(homeInfo.volumes);
            adjustVolume(context);
          }
        }));
  }

  /**
   * 调整音量
   */
  void adjustVolume(Context context) {
    List<Volume> volumes = KJDB.getDefaultInstance().findAll(Volume.class);
    if (volumes == null || volumes.size() == 0) {
      Slog.d(TAG, "adjustVolume  []:" + " no volume settings");
      return;
    }
    AudioUtil audioUtil = AudioUtil.getInstance(context);
    boolean tagchange0 = true;
    int volumenow = AudioUtil.getInstance(context).getMediaVolume();

    for (Volume volume : volumes) {
      long start = ChinaDateUtil.formateDataTolongMs(volume.start);
      long end = ChinaDateUtil.formateDataTolongMs(volume.end);
      long now = System.currentTimeMillis();
      boolean b = RangeUtil.INSTANCE.between(now, start, end);
      if (b && tagchange0) {
        tagchange0 = false;
        int volumeT = AudioUtil.getInstance(context).getMediaMaxVolume() * volume.audio / 100;

        if (volumeT == volumenow) {
          continue;
        }
        audioUtil.setMediaVolume(volumeT);
        Slog.d(TAG, "adjustVolume  [volumes]:" + volume.start + "~" + volume.end + "" + volumeT + " setSuccess");
      }
    }

    if (tagchange0 && volumenow != 0) {
      audioUtil.setMediaVolume(0);
    }
  }

  /**
   * 同步数据使用
   *
   * @param appDelegateBase
   * @return
   */
  Subscription syncStudentInfo(MainDelegate appDelegateBase, Action1<StudentsResponseS> action1) {
    if (appDelegateBase == null
        || ConfigDevice.DEMO_MODE
        || TextUtils.isEmpty(Api.get().getApi())) {
      return null;
    }
    return Api.get().getApi(ApiObserver.class)
        .students(ConfigDevice.getDeviceId(), ConfigDevice.school_id, null)
        .subscribeOn(Schedulers.newThread())
        .subscribe(new BaseRspObserver<>(StudentsResponseS.class, action1));
  }

  /**
   * 正常更新数据使用 需要传入时间戳
   *
   * @param appDelegateBase
   * @return
   */
  Subscription loadStudentInfo(MainDelegate appDelegateBase, Context context, Action1<StudentsResponseS> action1) {
    if (appDelegateBase == null
        || ConfigDevice.DEMO_MODE
        || TextUtils.isEmpty(Api.get().getApi())) {
      return null;
    }
    String updateTime = SPUtils.getInstance(context).get(ConstantsYJ.SpTag.STUDENT_INFO_UPDATE_TIME, "");
    return Api.get().getApi(ApiObserver.class)
        //TextUtils.isEmpty(updateTime) ? null : updateTime ==> 增量
        .students(ConfigDevice.getDeviceId(), ConfigDevice.school_id, null)
        .subscribeOn(Schedulers.newThread())
        .subscribe(new BaseRspObserver<>(StudentsResponseS.class, action1));
  }


  /**
   * 学生签到记录
   */
  public Subscription getStudentSignRecord(MainDelegate appDelegateBase) {
    if (appDelegateBase == null
        || ConfigDevice.DEMO_MODE
        || TextUtils.isEmpty(Api.get().getApi())) {
      return null;
    }
    return Api.get().getApi(ApiObserver.class)
        .getStudentSignRecord(ConfigDevice.getDeviceId(), ConfigDevice.school_id)
        .subscribeOn(Schedulers.newThread())
        .subscribe(new BaseRspObserver<>(StudentSignRecordResponseS.class, rsp -> {
          if (ErrorCode.isSuccess(rsp.error_code)) {
            KJDB.getDefaultInstance().deleteByWhere(StudentSignRecord.class, "1==1");
            if (rsp.data != null && !rsp.data.isEmpty()) {
              KJDB.getDefaultInstance().save(rsp.data);
            }
          }
        }));
  }

  /**
   * 上传抓拍记录
   */
  public Subscription uploadFailPhoto(TakePhotoRequest request, Action1<BaseResponse> action1) {
    if (ConfigDevice.DEMO_MODE
        || TextUtils.isEmpty(Api.get().getApi())) {
      return null;
    }
    return Api.get().getApi(ApiObserver.class)
        .uploadFailPhoto(ConfigDevice.school_id, request)
        .subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new BaseRspObserver<>(BaseResponse.class, action1));
  }

  /**
   * 刷卡签到
   */
  public Subscription swipeSign(SwipeRequest request, Action1<SwipeResponseS> action1) {
    if (ConfigDevice.DEMO_MODE
        || TextUtils.isEmpty(Api.get().getApi())) {
      return null;
    }
    return Api.get().getApi(ApiObserver.class)
        .swipeSign(ConfigDevice.school_id, request)
        .subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new BaseRspObserver<>(SwipeResponseS.class, action1));
  }

  /**
   * 刷脸签到
   */
  public Subscription allFaceSign(List<SwipeRequest> request, Action1<SwipeAllFaceResponseS> action1) {
    if (ConfigDevice.DEMO_MODE
        || TextUtils.isEmpty(Api.get().getApi())) {
      return null;
    }
    return Api.get().getApi(ApiObserver.class)
        .allFaceSign(ConfigDevice.school_id, request)
        .subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new BaseRspObserver<>(SwipeAllFaceResponseS.class, action1));
  }

  /**
   * 刷脸签到
   */
  public Subscription faceSign(FaceRequest request, Action1<SwipeResponseS> action1) {
    if (ConfigDevice.DEMO_MODE
        || TextUtils.isEmpty(Api.get().getApi())) {
      return null;
    }
    return Api.get().getApi(ApiObserver.class)
        .faceSign(ConfigDevice.school_id, request)
        .subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new BaseRspObserver<>(SwipeResponseS.class, action1));
  }

  /**
   * 获取家长相关学生
   *
   * @param union_id
   * @param swipe_time
   * @param action1
   * @return
   */
  public Subscription getParentLinkStudent(String union_id, String swipe_time, Action1<ParentLinkStudentsResponseS> action1) {
    if (ConfigDevice.DEMO_MODE
        || TextUtils.isEmpty(Api.get().getApi())) {
      return null;
    }
    return Api.get().getApi(ApiObserver.class)
        .getParentLinkStudent(ConfigDevice.school_id, union_id, swipe_time)
        .subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new BaseRspObserver<>(ParentLinkStudentsResponseS.class, action1));
  }


  public Subscription style(MainDelegate appDelegateBase, Context context) {
    if (appDelegateBase == null
        || ConfigDevice.DEMO_MODE
        || TextUtils.isEmpty(Api.get().getApi())) {
      return null;
    }
    return Api.get().getApi(ApiObserver.class)
        .style(ConfigDevice.school_id, ConfigDevice.getDeviceId(), "class_brand_config")
        .subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new BaseRspObserver<>(StyleResponseS.class, rsp -> {
          if (ErrorCode.isSuccess(rsp.error_code)) {
            KJDB.getDefaultInstance().deleteByWhere(OwnStyle.class, "1==1");
            if (rsp.data != null) {
              SPUtils.getInstance(context).put(ConstantsYJ.OWN_STYLE, rsp.data);
              AppConfig.setTakePhoto(rsp.data.photograph, context);
              AppConfig.setSpeak(rsp.data.announce, context);
              AppConfig.setShowPhoto(rsp.data.show_photo, context);
              AppConfig.setSwipeIntervalTime(rsp.data.swipe_interval_time, context);
            }
          } else {
            appDelegateBase.showShortToast(rsp.error_code, rsp.error_msg);
          }
          appDelegateBase.updateStyle();
        }));

  }

  /**
   * 加载通知通告
   */
  Subscription loadAnnounced(MainDelegate appDelegateBase) {
    if (appDelegateBase == null
        || ConfigDevice.DEMO_MODE
        || TextUtils.isEmpty(Api.get().getApi())) {
      return null;
    }
    return Api.get().getApi(ApiObserver.class)
        .announced(ConfigDevice.school_id, ConfigDevice.getDeviceId())
        .subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new BaseRspObserver<>(AnnouncedResponseS.class, rsp -> {
          if (ErrorCode.isSuccess(rsp.error_code)) {
            if (rsp.data != null && rsp.data.size() > 0) {
              List<Announced> data = new ArrayList<>();
              for (int i = 0; i < rsp.data.size(); i++) {
                Announced announced = new Announced();
                announced.title = rsp.data.get(i).title;
                announced.value = rsp.data.get(i).content;
                announced.is_top = rsp.data.get(i).is_top;
                announced.start_time = rsp.data.get(i).start_time;
                announced.end_time = rsp.data.get(i).end_time;
                data.add(announced);
              }
              KJDB.getDefaultInstance().deleteByWhere(Announced.class, "1=1");
              KJDB.getDefaultInstance().save(data);
            } else {
              KJDB.getDefaultInstance().deleteByWhere(Announced.class, "1=1");
            }
          }
          appDelegateBase.updateNotices();
        }));
  }

  /**
   * 二维码
   */
  Subscription getQrCodeUrl(MainDelegate appDelegateBase) {
    if (appDelegateBase == null
        || ConfigDevice.DEMO_MODE
        || TextUtils.isEmpty(Api.get().getApi())) {
      return null;
    }
    return Api.get().getApi(ApiObserver.class)
        .getQrCodeUrl(ConfigDevice.school_id, "attendance_scan_code")
        .subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new BaseRspObserver<>(QrCodeResponseS.class, rsp -> {
          if (ErrorCode.isSuccess(rsp.error_code)) {
            KJDB.getDefaultInstance().deleteByWhere(QrCode.class, "1==1");
            if (!TextUtils.isEmpty(rsp.data)) {
              KJDB.getDefaultInstance().save(new QrCode(rsp.data));
            }
          }
          appDelegateBase.updateQrCode();
        }));
  }


  /**
   * face链接地址
   *
   * @param appDelegateBase
   * @param type
   * @param action1
   * @return
   */
  Subscription getFaceUrl(MainDelegate appDelegateBase, String type, Action1<FaceUrlResponseS> action1) {
    PhpApi.get().setPhpApiConfig(BuildConfig.PHP_API_HOST_FACE, "", 0);
    return PhpApi.get().getPhpApi(ApiObserver.class)
        .getFaceUrl(ConfigDevice.school_id, BuildConfig.MASTER_KEY, ConfigDevice.getDeviceId(), type)
        .subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new BaseRspObserver<>(FaceUrlResponseS.class, action1));
  }

  /**
   * 上传特征值
   *
   * @param appDelegateBase
   * @param featuresUploadBeans
   * @param action1
   * @return
   */
  Subscription uploadFeatures(MainDelegate appDelegateBase, List<FeaturesUploadBean> featuresUploadBeans, Action1<BaseResponse> action1) {
    PhpApi.get().setPhpApiConfig(BuildConfig.PHP_API_HOST_FACE, "", 0);
    return PhpApi.get().getPhpApi(ApiObserver.class)
        .uploadFeatures(featuresUploadBeans, ConfigDevice.school_id, BuildConfig.MASTER_KEY)
        .subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new BaseRspObserver<>(BaseResponse.class, action1));
  }

  /**
   * 获取微服务信息
   */
  Subscription getAppsInfo(MainDelegate appDelegateBase, Context context) {
    if (appDelegateBase == null
        || ConfigDevice.DEMO_MODE
        || TextUtils.isEmpty(Api.get().getApi())) {
      return null;
    }
    return Api.get().getApi(ApiObserver.class)
        .getAppInfo(ConfigDevice.school_id, ConfigDevice.getDeviceId(), "terminal")
        .subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new BaseRspObserver<>(AppInfoRspS.class, rsp -> {
          if (ErrorCode.isSuccess(rsp.error_code)) {
            //保存整个小应用信息
            SPUtils.getInstance(context).put(ConstantsYJ.SpTag.APP_INFO, rsp);
          } else {
            appDelegateBase.showShortToast(rsp.error_code, rsp.error_msg);
          }
          appDelegateBase.updateApps();
        }));
  }

  /**
   * 获取设备硬件信息
   */
  Subscription getDeviceInfo(MainDelegate appDelegateBase, Context context, Action1<DeviceInfoRsp> action1) {
    if (appDelegateBase == null
        || ConfigDevice.DEMO_MODE
        || TextUtils.isEmpty(Api.get().getApi())) {
      return null;
    }
    return Api.get().getApi(ApiObserver.class)
        .getDeviceInfo(ConfigDevice.school_id, ConfigDevice.getDeviceId())
        .subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new BaseRspObserver<>(DeviceInfoRsp.class, action1));
  }

  /**
   * 获取最近三天的天气
   */
  Subscription get3DaysWeather(String location, MainDelegate appDelegateBase, Action1<WeatherResponseS> responseAction1) {
    if (appDelegateBase == null
        || ConfigDevice.DEMO_MODE
        || TextUtils.isEmpty(Api.get().getApi())) {
      return null;
    }
    return Api.get().getApi(ApiObserver.class)
        .get3DaysWeather(AppConfig.MASTER_KEY, location)
        .subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new BaseRspObserver<>(WeatherResponseS.class, responseAction1));
  }


  /**
   * 有些接口全局只需调用一次，但有失败的可能，可调用此方法重新获取数据
   *
   * @param action 到时自动回调
   */
//  private void reGetData(Context context, Action1<Long> action) {
//    Subscription subscription = Observable.timer(10L, TimeUnit.SECONDS).subscribe(action);
//    ((MainActivity) context).addRxSubscription(subscription);
//  }

  private final String TAG = getClass().getSimpleName();

  public List<BroadcastData> data;

  @Override
  public int describeContents() {
    return 0;
  }

  @Override
  public void writeToParcel(Parcel dest, int flags) {

  }

  private MainModel(Parcel in) {
  }

  public MainModel() {
  }

  public static final Creator<MainModel> CREATOR = new Creator<MainModel>() {
    @Override
    public MainModel createFromParcel(Parcel in) {
      return new MainModel(in);
    }

    @Override
    public MainModel[] newArray(int size) {
      return new MainModel[size];
    }
  };

  public Subscription getUpdataAppInfo(String deviceUuid, Action1<UpDateAppInfoResponseS> responseAction1) {
    PhpApi.get().setPhpApiConfig(BuildConfig.PHP_API_HOST, "", 0);
    UpDateAppInfoRequest request = new UpDateAppInfoRequest(deviceUuid, 15);
    return PhpApi.get().getPhpApi(ApiObserver.class)
        .getUpDataAppInfo(request)
        .subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new BaseRspObserver<>(UpDateAppInfoResponseS.class, responseAction1));
  }


  /**
   * 获取百度离线语音序列号
   *
   * @param appDelegateBase
   * @param mainActivity
   * @return
   */
  public Subscription getTTSerialNumber(MainDelegate appDelegateBase, MainActivity mainActivity) {
    if (appDelegateBase == null
        || ConfigDevice.DEMO_MODE
        || TextUtils.isEmpty(Api.get().getApi())) {
      return null;
    }
    return Api.get().getApi(ApiObserver.class)
        .getSerialNumber(ConfigDevice.school_id, ConfigDevice.getDeviceId())
        .subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new BaseRspObserver<>(SerialNumberS.class, rsp -> {
          if (ErrorCode.isSuccess(rsp.error_code)) {
            SPUtils.getInstance(mainActivity).put("serial_number", rsp.extra.SerialNumber);
          } else {
            appDelegateBase.showShortToast(rsp.error_code, rsp.error_msg);
          }
        }));
  }

  public Subscription xiaoxun(MainDelegate viewDelegate, Context context) {
    if (viewDelegate == null || ConfigDevice.DEMO_MODE) {
      return null;
    }
    return Api.get().getApi(ApiObserver.class,BuildConfig.PHP_API_HOST_FACE)
            .Motto(BuildConfig.MASTER_KEY,ConfigDevice.school_id)
            .subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new BaseRspObserver<>(MottoResponseS.class, rsp -> {
              if (ErrorCode.isSuccess(rsp.error_code)) {
                if (rsp.extra.items.size() != 0) {
                  SPUtils.getInstance(context).put(ConstantsYJ.XIAOXUN_STYLE, rsp.extra.items.get(0));
                }
              } else {
                viewDelegate.showShortToast(rsp.error_code, rsp.error_msg);
              }
              viewDelegate.updateXiaoXun();
            }));
  }

  public Subscription getIOTConfig(MainDelegate viewDelegate, String access_token, IOTConfigRequest iotConfigRequest){
    if (viewDelegate == null || ConfigDevice.DEMO_MODE) {
      return null;
    }
    return Api.get().getApi(ApiObserver.class,BuildConfig.IOT_HOST)
            .config_iot("Bearer " + access_token,iotConfigRequest)
            .subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new BaseRspObserver<>(IOTConfigResponseS.class, rsp -> {
                if (rsp.error_code == 0) {
                  SPUtils.getInstance(viewDelegate.getActivity()).put(ConstantsYJ.IOT_CONFIG, rsp.data);
              }
              viewDelegate.updateIOTConfig();
            }));
  }
}
